<template>
  <div>
    <!-- 文章内容基础显示 -->
    <el-card class="box-card">
      <div slot="header" class="clearfix header-box">
        <span>文章分类</span>
        <el-button type="primary" size="mini" @click="addCateBtnFn"
          >添加分类</el-button
        >
      </div>
      <!-- :data="artCateList" 显示数据 -->
      <el-table :data="artCateList" style="width: 100%" border stripe>
        <el-table-column
          type="index"
          label="序号"
          width="100"
          align="center"
        ></el-table-column>
        <!-- prop要跟数据对上 -->
        <el-table-column prop="cate_name" label="分类名称"></el-table-column>
        <el-table-column prop="cate_alias" label="分类别名"></el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button
              type="primary"
              size="mini"
              @click="updateArtCateHandler(scope.row)"
              >修改</el-button
            >
            <el-button
              type="danger"
              size="mini"
              @click="delArtCateHandler(scope.row.id)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 对话框组件 -->
    <el-dialog
      :title="isEdit ? '编辑文章分类' : '添加文章分类'"
      :visible.sync="dialogFormVisible"
      width="35%"
      @closed="resetFormHandle"
    >
      <el-form
        :model="addForm"
        label-width="80px"
        :rules="addRules"
        ref="addRef"
      >
        <el-form-item label="分类名称" prop="cate_name">
          <el-input v-model="addForm.cate_name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="分类别名" prop="cate_alias">
          <el-input v-model="addForm.cate_alias" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="cancleArtHandler">取 消</el-button>
        <el-button type="primary" @click="addArtHandler">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
// 经验：如果用同一个按钮，要做状态区分
// 1. 定义一个标记变量isEdit，（true编辑，false新增），还要定义本次要编辑的数据唯一的id值，editId
// 2. 在点击修改数据回显的时候，isEdit改为true，editId保存起来
// 3. 点击新增的时候，isEdit改为false，editId置空
// 4. 点击保存的时候，就可以使用isEdit做区分。
import {
  getArticleCategoryAPI,
  addArticleCategoryAPI,
  updateArticleCategoryAPI,
  delArticleCategoryAPI,
} from '@/api'
export default {
  name: 'ArtCate',
  data() {
    return {
      artCateList: [], // 文章的分类列表
      dialogFormVisible: false, // 添加分类-对话框是否显示
      // 添加文章分类表单的数据对象
      addForm: {
        cate_name: '',
        cate_alias: '',
      },
      // 添加文章分类表单的验证规则
      addRules: {
        cate_name: [
          { required: true, message: '请输入分类名称', trigger: 'blur' },
          {
            pattern: /^\S{1,10}$/,
            message: '分类名必须是1-10位的非空字符',
            trigger: 'blur',
          },
        ],
        cate_alias: [
          { required: true, message: '请输入分类别名', trigger: 'blur' },
          {
            pattern: /^[a-zA-Z0-9]{1,15}$/,
            message: '分类别名必须是1-15位的字母数字',
            trigger: 'blur',
          },
        ],
      },
      // 保存编辑状态(false新增, true编辑)
      isEdit: false,
      // 要修改的文章id
      editId: '',
    }
  },
  created() {
    // 获取文章分类
    this.loadArtCate()
  },
  methods: {
    // 获取文章分类
    async loadArtCate() {
      const res = await getArticleCategoryAPI()
      this.artCateList = res.data.data
    },
    // 确定添加文章分类
    addArtHandler() {
      this.$refs.addRef.validate(async (valid) => {
        if (!valid) return false
        if (this.isEdit) {
          // 编辑状态 调接口更新文章分类
          const res = await updateArticleCategoryAPI({
            id: this.editId,
            ...this.addForm,
          })
          if (res.data.code !== 0) return this.$message.error(res.data.message)
          this.$message.success(res.data.message)
        } else {
          // 非编辑状态 调接口添加文章分类
          const res = await addArticleCategoryAPI(this.addForm)
          if (res.data.code !== 0) return this.$message.error(res.data.message)
          this.$message.success(res.data.message)
        }

        // 重新请求文章分类列表数据
        this.loadArtCate()
        // 关闭对话框
        this.dialogFormVisible = false
      })
    },
    // 取消添加文章分类
    cancleArtHandler() {
      // 关闭对话框
      this.dialogFormVisible = false
    },
    // 监听对话框的 closed 事件,当关闭对话框的时候，清空表单输入的内容
    resetFormHandle() {
      this.$refs.addRef.resetFields()
    },
    // 点击右上角添加分类按钮
    addCateBtnFn() {
      // 打开对话框
      this.dialogFormVisible = true
      // 编辑状态改为false
      this.isEdit = false
      // 设置文章id为空
      this.edit = ''
    },
    // 修改文章，回显数据
    updateArtCateHandler(obj) {
      // 1.显示对话框，2.保存要编辑的文章分类ID，3.设置编辑状态
      this.dialogFormVisible = true
      this.editId = obj.id // 保存id，后面更新文章的接口需要
      this.isEdit = true
      // 4. 回显数据，如果先点击修改在点击新增，会出现bug，
      // 解决办法：让数据慢点执行,先让对话框出现, 它绑定空值的对象, 才能resetFields清空用初始空值
      // 注意： 我们给v-model对象赋值只是影响当前显示的值，不会影响到 resetFields 复制的初始值
      this.$nextTick(() => {
        this.addForm.cate_name = obj.cate_name
        this.addForm.cate_alias = obj.cate_alias
      })
    },
    // 删除文章分类
    async delArtCateHandler(id) {
      // 1. 询问用户是否要删除
      const confirmResult = await this.$confirm(
        '此操作将永久删除该文章, 是否继续?',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
      ).catch((err) => err)
      // 2. 取消了删除
      if (confirmResult === 'cancel') return

      const res = await delArticleCategoryAPI(id)
      if (res.data.code !== 0) return this.$message.error(res.data.message)
      this.$message.success(res.data.message)
      // 重新请求文章分类列表数据
      this.loadArtCate()
    },
  },
}
// 小bug：
// 发现：第一次打开网页，先点击修改，再点击新增，发现输入框竟然有值
// 原因：点击修改后，关闭对话框的时候，置空失效了
// 分析：resetFields 有问题，没出效果
// 线索：1. Dialog 的内容是懒渲染的，即在第一次被打开之前，传入的默认值 slot 不会被渲染到dom上，第二次后续只是做css隐藏和显示
//      2. vue数据改变（先执行同步所有）再去更新dom（异步代码）
// 无问题：第一次打开网页，先点击新增 -> dialog出现 —> el-form组件第一次挂载（addFrom里的属性为空字符串）-> el-form组件内绑定初始值，所以后续调用 resetFields 的时候，他可以用到空字符串初始值来重置
// 有问题：第一次打开网页，先点击修改 -> dialog出现 -> 虽然dialog出现了但是同步代码把addForm对象里的变量赋值了，就是obj传过来的值 -> dom更新异步 -> 再点击新增 -> dialog出现 -> el-form组件第一次挂载（使用addFrom的数据做回显，有值）-> 以后做重置，他就用绑定的带值做重置
// 解决办法：让数据回显慢点执行，使用$nextTick等待下一次dom更新完成执行指定的回调。
</script>

<style lang="scss" scoped>
.header-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
